import type { RequestOptions, ResponseData } from '../types';
import config from '@/utils/request/config';
import { useUserStore } from '@/stores';

const { token } = useUserStore();

const xhrAdapter = <T>(url: string, options: RequestOptions): Promise<ResponseData<T>> => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    // 处理请求参数
    let fullUrl = url;
    if (options.params) {
      const params = new URLSearchParams();
      for (const [key, value] of Object.entries(options.params)) {
        if (value !== undefined && value !== null) {
          params.append(key, String(value));
        }
      }
      fullUrl += `?${params.toString()}`;
    }

    xhr.open(options.method || 'GET', fullUrl, true);

    // 设置请求头
    const headers = {
      ...config.DEFAULT_HEADERS,
      ...(token ? { 'X-XSRF-TOKEN': token } : {}),
      ...options.headers,
    };

    for (const [key, value] of Object.entries(headers)) {
      xhr.setRequestHeader(key, value);
    }

    xhr.withCredentials = true; // 携带cookie
    xhr.timeout = options.timeout || config.TIMEOUT;

    if (options.signal) {
      options.signal.addEventListener('abort', () => {
        xhr.abort();
      });
    }

    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        let responseData: any;

        try {
          responseData = xhr.responseText && JSON.parse(xhr.responseText);
        } catch {
          responseData = xhr.responseText;
        }

        // 将响应头转换为对象
        const headers = xhr
          .getAllResponseHeaders()
          .split('\r\n')
          .reduce((acc: Record<string, string>, line) => {
            const [key, value] = line.split(': ');
            if (key) acc[key.toLowerCase()] = value;
            return acc;
          }, {});

        resolve({
          status: xhr.status,
          statusText: xhr.statusText,
          headers,
          data: responseData as T,
        });
      } else {
        reject(new Error(`HTTP error! status: ${xhr.status}`));
      }
    };

    xhr.onerror = () => {
      reject(new Error('Network error'));
    };

    xhr.ontimeout = () => {
      reject(new Error('Request timeout'));
    };

    if (options.data) {
      xhr.send(JSON.stringify(options.data));
    } else {
      xhr.send();
    }
  });
};

export default xhrAdapter;
